package com.hkts.beltweigher.config.jwt;


import com.google.gson.Gson;

import com.hkts.beltweigher.annotation.SystemLog;
import com.hkts.beltweigher.config.Constant.SecurityConstant;
import com.hkts.beltweigher.config.properties.TokenProperties;
import com.hkts.beltweigher.enums.LogType;
import com.hkts.beltweigher.master.entity.TokenUser;
import com.hkts.beltweigher.master.entity.User;
import com.hkts.beltweigher.master.service.IUserService;
import com.hkts.beltweigher.utils.ResponseUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private TokenProperties tokenProperties;
    @Autowired
    public IUserService iUserService;
    @SneakyThrows
    @Override
    @SystemLog(description = "登录系统", type = LogType.LOGIN)
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String loginType = request.getParameter("loginType");
        String username = ((UserDetails)authentication.getPrincipal()).getUsername();
        Map<String, Object> resultMap = new HashMap<String, Object>(16);


        //用户选择保存登录状态几天
        String saveLogin = request.getParameter(SecurityConstant.SAVE_LOGIN);
        String code = request.getParameter("code");
       // System.out.println(code);
        Boolean saved = false;
        if(StringUtils.isNotBlank(saveLogin) && Boolean.valueOf(saveLogin)){
            saved = true;
            if(!tokenProperties.getRedis()){
                tokenProperties.setTokenExpireTime(tokenProperties.getSaveLoginTime() * 60 * 24);
            }
        }

        List<GrantedAuthority> authorities = (List<GrantedAuthority>) ((UserDetails)authentication.getPrincipal()).getAuthorities();
        List<String> list = new ArrayList<>();

        // 登陆成功生成token
        String token;
        if(tokenProperties.getRedis()){
            // redis
            token = UUID.randomUUID().toString().replace("-", "");
            TokenUser user = new TokenUser(username, list, saved);
            // 不缓存权限
            if(!tokenProperties.getStorePerms()){
                user.setPermissions(null);
            }
            // 单设备登录 之前的token失效
            if(tokenProperties.getSdl()){
                String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + username);
                if(StringUtils.isNotBlank(oldToken)){
                    redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
                }
            }
            if(saved){
                redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, token, tokenProperties.getSaveLoginTime(), TimeUnit.DAYS);
                redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), tokenProperties.getSaveLoginTime(), TimeUnit.DAYS);
            }else{
                redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, token, tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
                redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
            }
        }else{
            // 不缓存权限
            if(!tokenProperties.getStorePerms()){
                list = null;
            }
            // jwt
            token = SecurityConstant.TOKEN_SPLIT + Jwts.builder()
                    //主题 放入用户名
                    .setSubject(username)
                    //自定义属性 放入用户拥有请求权限
                    .claim(SecurityConstant.AUTHORITIES, new Gson().toJson(list))
                    //失效时间
                    .setExpiration(new Date(System.currentTimeMillis() + tokenProperties.getTokenExpireTime() * 60 * 1000))
                    //签名算法和密钥
                    .signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY)
                    .compact();
        }

        resultMap.put("success", true);
        resultMap.put("message", "success");
        resultMap.put("code", 200);
        resultMap.put("timestamp", System.currentTimeMillis());
        resultMap.put("token", token);
        resultMap.put("result", token);
        ResponseUtil.out(response, resultMap);
        User user = (User)authentication.getPrincipal();


   /*     CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            log.info("异步处理数据回写");
            Getid gid = new Getid();
            try {
                String openid = gid.getUserInfo(code);
                if (user.getOpenId() == null || user.getOpenId().equals("") || !user.getOpenId().equals(openid) ){
                    user.setOpenId(openid);
                    hontUserService.updateOpenId(user);
                }
                user.setUpdateLastTime(new Date());
                hontUserService.updateLastTime(user);
            }catch (Exception e){
                e.printStackTrace();
            }

        });*/
    }
}
